﻿package com.boyaa.shells.tool.slider
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	
	/**
	 * 滑块 资源组成
	 * upBtn
	 * downBtn
	 * track
	 * sliderBar 包含 top - middle - bottom 三个剪辑
	 * 
	 * 使用说明:
	 * 创建新的EasySlide对象后
	 * １.调用setBarHeight()方法，此方法根据滑块的最大高度、滚动列表的最大行数和每页可容纳的行数来计算滑块实际的高度
	 * ２.调用setScrollRange()方法，该方法只有一个参数，并且是可选的。该方法用来计算滑块的滚动范围，其中的参数offset
	 * 		是用来微调滑块滚动范围的
	 * ３.添加事件侦听addEvent()；
	 * ４.speed属性为可选参数，是用来控制滑块滚动速度的；
	 * ５.ｘ和ｙ属性可以控制显示对象的坐标
	 * 
	 * @author Kevin
	 */
	public class EasySlider extends EventDispatcher
	{	
		////////////////////////////////////////////////////////////////////////////////
		//需要鼠标效果的显示对象
		private const LIST:Array = ["scrollDown", "scrollUp", "bar"];
		////////////////////////////////////////////////////////////////////////////////
		//
		private var _sliderView:MovieClip = null;		// 滑块资源
		private var _scrollUp:SimpleButton = null;		// 向上滚动按钮
		private var _scrollDown:SimpleButton = null;	// 向下滚动
		private var _scrollTrack:MovieClip = null;		// 滑轨
		
		private var _sliderBar:SliderBar = null;		// 滑块控制
		private var _bar:MovieClip = null;				// 滑块	
		
		////////////////////////////////////////////////////////////////////////////////
		// 基本属性
		private var _pageCount:int = 0;					// 单页行数
		private var _maxCount:int = 0;					// 最大行数
		private var _maxBarHeight:Number = 0;			// 滑块最大高度
		private var _speed:Number = 1;					// 滚动速度
		
		private var _value:Number = 0;					// 滑块值
		
		////////////////////////////////////////////////////////////////////////////////
		// 运行时参数
		private var _min:Number = 0;					// 滑块的最小滚动坐标
		private var _max:Number = 0;					// 滑块的最大滚动坐标
		
		private var _currentBtn:SimpleButton = null;	// 当前按钮
		private var _isDrag:Boolean = false;			// 是否拖动了
		
		
		/**
		 * 构造函数
		 * @param	sliderView	滑块剪辑
		 * @param	scrollObj	需要滚动的显示对象
		 */
		public function EasySlider(sliderView:MovieClip) 		
		{		
			_sliderView = sliderView;
			_scrollUp = _sliderView.upBtn;
			_scrollDown = _sliderView.downBtn;
			_scrollTrack = _sliderView.track;
			_bar = _sliderView.sliderBar;
			
			// 滑块
			_sliderBar = new SliderBar(_bar);	
			_sliderBar.hideBar();
			
		}
		
		//------------------------------------------------------------------------------------------------------//
		//												公开API													//
		//------------------------------------------------------------------------------------------------------//
		/**
		 * 设置参数
		 * @param	pageCount
		 * @param	maxCount
		 */
		public function setBarHeight(pageCount:Number,maxCount:Number, sliderHeight:Number = -1):void
		{
			_pageCount = pageCount;
			_maxCount = maxCount;
			_scrollTrack.height = (sliderHeight == -1) ? _scrollTrack.height:(sliderHeight - _scrollDown.height / 2 - _scrollUp.height / 2);
			_maxBarHeight = _scrollTrack.height - _scrollDown.height / 2 - _scrollUp.height / 2;			
			
			sliderHeight = _maxBarHeight * _pageCount / _maxCount;			
			
			if (sliderHeight >= _maxBarHeight || _maxCount <= _pageCount)
			{				
				_sliderBar.hideBar();
				removeEvent();
			}				
			else
			{
				_sliderBar.height = sliderHeight;
				addEvent();
				_sliderBar.showBar();				
			}
		}
		
		/**
		 * 设置滚动范围
		 * @param	offset	上下偏移
		 */
		public function setScrollRange(offset:Number = 0):void
		{
			_scrollUp.y = _scrollTrack.y;
			_scrollDown.y = _scrollTrack.y +_scrollTrack.height;
			
			_min = _scrollTrack.y + _scrollUp.height / 2 + offset;
			_max = _scrollTrack.y + _scrollTrack.height - _scrollDown.height / 2 - _sliderBar.height - offset;			
			
			_min = Math.round(_min);
			_max = Math.round(_max);
			
			_sliderBar.y = _min;
			
			_speed = (_max - _min) / (_maxCount - _pageCount) / 4;	// 每滚动一次滚轮，列表会移动行高的１／５
			
		}
		/**
		 * 添加事件
		 */
		private function addEvent():void
		{
			_scrollUp.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);			
			_scrollDown.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
			_bar.addEventListener(MouseEvent.MOUSE_DOWN, dragHandler);
			_sliderView.parent.addEventListener(MouseEvent.MOUSE_WHEEL, wheelHandler);
			_scrollTrack.addEventListener(MouseEvent.MOUSE_DOWN, trackDownHandler);
			
			// 添加鼠标效果
			addMouseEffect(true);
			_scrollUp.mouseEnabled = true;
			_scrollDown.mouseEnabled = true;
			_scrollTrack.mouseEnabled = true;
		}		
		
		/**
		 * 移除事件
		 */
		private function removeEvent():void
		{
			_scrollUp.removeEventListener(MouseEvent.MOUSE_DOWN, downHandler);
			_scrollDown.removeEventListener(MouseEvent.MOUSE_DOWN, downHandler);
			_bar.removeEventListener(MouseEvent.MOUSE_DOWN, dragHandler);
			_bar.removeEventListener(Event.ENTER_FRAME, scrollHandler);
			_sliderView.parent.removeEventListener(MouseEvent.MOUSE_WHEEL, wheelHandler);
			_scrollTrack.removeEventListener(MouseEvent.MOUSE_DOWN, trackDownHandler);
			
			// 移除鼠标效果
			addMouseEffect(false);
		}
		
		/**
		 * 添加鼠标效果
		 * @param	isAdd
		 */
		private function addMouseEffect(isAdd:Boolean):void
		{
			for (var i:int = 0; i < LIST.length; i++)
			{
				//MouseHandler.addMouseEffect(this["_" +LIST[i]], isAdd);
			}
		}
		
		/**
		 * 滑轨点击事件
		 * @param	e
		 */
		private function trackDownHandler(e:MouseEvent):void 
		{
			if (e.localY > _sliderBar.y)
				_speed = Math.abs(_speed);
			else
				_speed = -Math.abs(_speed)
			_bar.addEventListener(Event.ENTER_FRAME, scrollHandler);
			_bar.stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
		}
		
		/**
		 * 滚轮事件
		 * @param	e
		 */
		private function wheelHandler(e:MouseEvent):void 
		{
			_sliderBar.y -= Math.abs(_speed) * Math.abs(e.delta) / e.delta; 
			adjustPosition();
			_value = 100 * (_sliderBar.y - _min) / (_max - _min);	
			dispatchEvent(new Event(Event.CHANGE));			
			
		}
		
		//------------------------------------------------------------------------------------------------------//
		//												私有方法													//
		//------------------------------------------------------------------------------------------------------//
		/**
		 * 滑块拖动处理
		 * @param	e
		 */
		private function dragHandler(e:MouseEvent):void 
		{
			_sliderBar.select(true);
			_bar.startDrag(false, new Rectangle(0, _min, 0, _max - _min));
			_isDrag = true;
			_bar.stage.addEventListener(MouseEvent.MOUSE_UP, stopDragHandler);
			_bar.addEventListener(Event.ENTER_FRAME, scrollHandler);
		}
		
		/**
		 * 停止拖动处理
		 * @param	e
		 */
		private function stopDragHandler(e:MouseEvent):void 
		{
			_sliderBar.select(false);
			_bar.stopDrag();
			_isDrag = false;
			e.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, stopDragHandler);
			_bar.removeEventListener(Event.ENTER_FRAME, scrollHandler);
		}
		
		//------------------------------------------------------------------------------------------------------//
		//													点击处理												//
		//------------------------------------------------------------------------------------------------------//
		/**
		 * 按钮点击
		 * @param	e
		 */
		private function downHandler(e:MouseEvent):void 
		{
			if (e.currentTarget == _scrollUp)
			{
				_speed = -Math.abs(_speed);				
				_currentBtn = _scrollUp;
			}
			else
			{
				_speed = Math.abs(_speed);				
				_currentBtn = _scrollDown;
			}
			
			_bar.addEventListener(Event.ENTER_FRAME, scrollHandler);
			_currentBtn.stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
		}
		
		/**
		 * 
		 * @param	e
		 */
		private function scrollHandler(e:Event):void 
		{			
			if(_isDrag)
				_sliderBar.y = _bar.y;
			else
				_sliderBar.y += _speed;				
				
			adjustPosition();
			
			_value = 100 * (_sliderBar.y - _min) / (_max - _min);			
			dispatchEvent(new Event(Event.CHANGE));						// 通知外部接收事件
		}
		
		/**
		 * 检查滑块的竖坐标
		 * @return
		 */
		private function adjustPosition():Boolean
		{
			if (_sliderBar.y < _min)
			{
				_sliderBar.y = _min;
				return false;
			}
			
			if (_sliderBar.y > _max)
			{
				_sliderBar.y = _max;
				return false;
			}			
			return true;			
		}
		
		/**
		 * 
		 * @param	e
		 */
		private function upHandler(e:MouseEvent):void 
		{
			_bar.removeEventListener(Event.ENTER_FRAME, scrollHandler);
			e.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, upHandler);
		}
		
		//------------------------------------------------------------------------------------------------------//
		//											Setters														//
		//------------------------------------------------------------------------------------------------------//
		/**
		 * 单页的行数
		 */
		public function set pageCount(value:int):void 
		{
			_pageCount = value;
		}		
		
		/**
		 * 总行数
		 */
		public function set maxCount(value:int):void 
		{
			_maxCount = value;
		}
		
		/**
		 * 滚动速度
		 */
		public function set speed(value:Number):void 
		{
			_speed = value;
		}
		
		/**
		 * 滑块输出值
		 */
		public function get value():Number { return _value; }		
		public function set value(value:Number):void 
		{
			_value = value;
			_sliderBar.y = _value * (_max -_min) / 100 + _min;
			dispatchEvent(new Event(Event.CHANGE));
		}
		
		/**
		 * 滑块竖坐标
		 */	
		public function get x():Number { return _sliderView.x; }
		public function set x(value:Number):void 
		{		
			_sliderView.x = value;
		}
		
		/**
		 * 被滚动对象竖坐标
		 */
		public function get y():Number { return _sliderView.y; }
		public function set y(value:Number):void 
		{			
			_sliderView.y = value;
		}
		
		/**
		 * 滑块宽度
		 */
		public function get width():Number { return _sliderView.width; }
	}
	
}